#ifndef SOCKET_H_
#define SOCKET_H_

#include <unistd.h>

#include "netlib/base/logger.h"
// #include "netlib/base/noncopyable.h"
// #include "netlib/net/socket/inet_address.h"
#include "netlib/net/socket/socket_ops.h"

namespace netlib::net {

class Socket : public NonCopyable {
public:
	explicit Socket(const InetAddress& addr) :
	    kSockfd(socket(addr.Family(), SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP)) {
		assert(kSockfd > 0);
	}
	explicit Socket(int fd) : kSockfd(fd) {}
	~Socket() {
		close(kSockfd);
		// LOG_INFO << "close connection";
	}

	int Fd() const { return kSockfd; }

	void Listen() const { sockets::ListenOrDie(kSockfd); }
	void Bind(const sockaddr* addr) const { sockets::BindOrDie(kSockfd, addr); }
	int Accept(InetAddress* peeraddr) const {
		struct sockaddr_in6 addr;
		memset(&addr, '\0', sizeof addr);
		int connfd = sockets::Accept(kSockfd, &addr);
		if (connfd >= 0) {
			peeraddr->SetAddr6(addr);
		}
		return connfd;
	}

private:
	const int kSockfd;
};

} // namespace netlib::net

#endif // SOCKET_H_